package org.parademo.service.security;

import org.parademo.dao.UserDao;
import org.parademo.model.UserEntity;
import org.springframework.dao.DataAccessException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.GrantedAuthorityImpl;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;

import java.util.Arrays;
import java.util.Collection;

public class ParademoUserDetailsService implements UserDetailsService {
    private final UserDao userDao;

    public ParademoUserDetailsService(UserDao userDao) {
        this.userDao = userDao;
    }

    @Override
    public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException, DataAccessException {
        UserEntity userEntity = (UserEntity) userDao.retrieve(userName);

        if (userEntity == null) {
            throw new UsernameNotFoundException("cannot find user with userName=[" + userName + "] in the database");
        }

        boolean enabled = true;
        boolean accountNonExpired = true;
        boolean credentialsNonExpired = true;
        boolean accountNonLocked = true;

        ParademoUser user = new ParademoUser(
                userEntity.getUserName(),
                userEntity.getPassword(),
                enabled,
                accountNonExpired,
                credentialsNonExpired,
                accountNonLocked,
                getGrantedAuthorities(userEntity)
        );

        user.setId(
                userEntity.getId()
        );

        user.setFirstName(
                userEntity.getFirstName()
        );
        user.setLastName(
                userEntity.getLastName()
        );
        user.setBirthDate(
                userEntity.getBirthDate()
        );
        user.setJoinDate(
                userEntity.getJoinDate()
        );

        return user;
    }

    private Collection<? extends GrantedAuthority> getGrantedAuthorities(UserEntity user) {
        // normally this method would return something like the list of security groups (or roles) this user is part of
        return Arrays.asList(
                new GrantedAuthorityImpl("ROLE_USER")
        );
    }
}
